home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / inetutil.1 / inetutil / inetutils-1.1 / libtelnet / spx.c < prev   
Encoding:
C/C++ Source or Header  |  1996-07-22  |  18.6 KB  |  593 lines

  1. /*-
  2.  * Copyright (c) 1992, 1993
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)spx.c    8.2 (Berkeley) 5/30/95";
  36. #endif /* not lint */
  37.  
  38. #ifdef    SPX
  39. /*
  40.  * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
  41.  * ALL RIGHTS RESERVED
  42.  *
  43.  * "Digital Equipment Corporation authorizes the reproduction,
  44.  * distribution and modification of this software subject to the following
  45.  * restrictions:
  46.  *
  47.  * 1.  Any partial or whole copy of this software, or any modification
  48.  * thereof, must include this copyright notice in its entirety.
  49.  *
  50.  * 2.  This software is supplied "as is" with no warranty of any kind,
  51.  * expressed or implied, for any purpose, including any warranty of fitness
  52.  * or merchantibility.  DIGITAL assumes no responsibility for the use or
  53.  * reliability of this software, nor promises to provide any form of
  54.  * support for it on any basis.
  55.  *
  56.  * 3.  Distribution of this software is authorized only if no profit or
  57.  * remuneration of any kind is received in exchange for such distribution.
  58.  *
  59.  * 4.  This software produces public key authentication certificates
  60.  * bearing an expiration date established by DIGITAL and RSA Data
  61.  * Security, Inc.  It may cease to generate certificates after the expiration
  62.  * date.  Any modification of this software that changes or defeats
  63.  * the expiration date or its effect is unauthorized.
  64.  *
  65.  * 5.  Software that will renew or extend the expiration date of
  66.  * authentication certificates produced by this software may be obtained
  67.  * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
  68.  * 94065, (415)595-8782, or from DIGITAL"
  69.  *
  70.  */
  71.  
  72. #ifdef HAVE_CONFIG_H
  73. #include <config.h>
  74. #endif
  75.  
  76. #include <sys/types.h>
  77. #include <arpa/telnet.h>
  78. #include <stdio.h>
  79. #include "gssapi_defs.h"
  80. #ifdef    __STDC__
  81. #include <stdlib.h>
  82. #endif
  83. #ifdef    NO_STRING_H
  84. #include <strings.h>
  85. #else
  86. #include <string.h>
  87. #endif
  88.  
  89. #include <pwd.h>
  90. #include "encrypt.h"
  91. #include "auth.h"
  92. #include "misc.h"
  93.  
  94. extern auth_debug_mode;
  95.  
  96. static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
  97.                       AUTHTYPE_SPX, };
  98. static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
  99.                     TELQUAL_NAME, };
  100.  
  101. #define    SPX_AUTH    0        /* Authentication data follows */
  102. #define    SPX_REJECT    1        /* Rejected (reason might follow) */
  103. #define SPX_ACCEPT    2        /* Accepted */
  104.  
  105. #ifdef    ENCRYPTION
  106. static Block    session_key    = { 0 };
  107. #endif    /* ENCRYPTION */
  108. static Schedule sched;
  109. static Block    challenge    = { 0 };
  110.  
  111.  
  112. /*******************************************************************/
  113.  
  114. gss_OID_set           actual_mechs;
  115. gss_OID               actual_mech_type, output_name_type;
  116. int                   major_status, status, msg_ctx = 0, new_status;
  117. int                   req_flags = 0, ret_flags, lifetime_rec;
  118. gss_cred_id_t         gss_cred_handle;
  119. gss_ctx_id_t          actual_ctxhandle, context_handle;
  120. gss_buffer_desc       output_token, input_token, input_name_buffer;
  121. gss_buffer_desc       status_string;
  122. gss_name_t            desired_targname, src_name;
  123. gss_channel_bindings  input_chan_bindings;
  124. char                  lhostname[GSS_C_MAX_PRINTABLE_NAME];
  125. char                  targ_printable[GSS_C_MAX_PRINTABLE_NAME];
  126. int                   to_addr=0, from_addr=0;
  127. char                  *address;
  128. gss_buffer_desc       fullname_buffer;
  129. gss_OID               fullname_type;
  130. gss_cred_id_t         gss_delegated_cred_handle;
  131.  
  132. /*******************************************************************/
  133.  
  134.  
  135.  
  136.     static int
  137. Data(ap, type, d, c)
  138.     Authenticator *ap;
  139.     int type;
  140.     void *d;
  141.     int c;
  142. {
  143.         unsigned char *p = str_data + 4;
  144.     unsigned char *cd = (unsigned char *)d;
  145.  
  146.     if (c == -1)
  147.         c = strlen((char *)cd);
  148.  
  149.         if (0) {
  150.                 printf("%s:%d: [%d] (%d)",
  151.                         str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
  152.                         str_data[3],
  153.                         type, c);
  154.                 printd(d, c);
  155.                 printf("\r\n");
  156.         }
  157.     *p++ = ap->type;
  158.     *p++ = ap->way;
  159.     *p++ = type;
  160.         while (c-- > 0) {
  161.                 if ((*p++ = *cd++) == IAC)
  162.                         *p++ = IAC;
  163.         }
  164.         *p++ = IAC;
  165.         *p++ = SE;
  166.     if (str_data[3] == TELQUAL_IS)
  167.         printsub('>', &str_data[2], p - (&str_data[2]));
  168.         return(net_write(str_data, p - str_data));
  169. }
  170.  
  171.     int
  172. spx_init(ap, server)
  173.     Authenticator *ap;
  174.     int server;
  175. {
  176.         gss_cred_id_t    tmp_cred_handle;
  177.  
  178.     if (server) {
  179.         str_data[3] = TELQUAL_REPLY;
  180.         gethostname(lhostname, sizeof(lhostname));
  181.         strcpy(targ_printable, "SERVICE:rcmd@");
  182.         strcat(targ_printable, lhostname);
  183.         input_name_buffer.length = strlen(targ_printable);
  184.         input_name_buffer.value = targ_printable;
  185.         major_status = gss_import_name(&status,
  186.                                        &input_name_buffer,
  187.                                        GSS_C_NULL_OID,
  188.                                        &desired_targname);
  189.         major_status = gss_acquire_cred(&status,
  190.                                         desired_targname,
  191.                                         0,
  192.                                         GSS_C_NULL_OID_SET,
  193.                                         GSS_C_ACCEPT,
  194.                                         &tmp_cred_handle,
  195.                                         &actual_mechs,
  196.                                         &lifetime_rec);
  197.         if (major_status != GSS_S_COMPLETE) return(0);
  198.     } else {
  199.         str_data[3] = TELQUAL_IS;
  200.     }
  201.     return(1);
  202. }
  203.  
  204.     int
  205. spx_send(ap)
  206.     Authenticator *ap;
  207. {
  208.     Block enckey;
  209.     int r;
  210.  
  211.     gss_OID  actual_mech_type, output_name_type;
  212.     int           msg_ctx = 0, new_status, status;
  213.     int           req_flags = 0, ret_flags, lifetime_rec, major_status;
  214.     gss_buffer_desc  output_token, input_token, input_name_buffer;
  215.     gss_buffer_desc  output_name_buffer, status_string;
  216.     gss_name_t    desired_targname;
  217.     gss_channel_bindings  input_chan_bindings;
  218.     char targ_printable[GSS_C_MAX_PRINTABLE_NAME];
  219.     int  from_addr=0, to_addr=0, myhostlen, j;
  220.     int  deleg_flag=1, mutual_flag=0, replay_flag=0, seq_flag=0;
  221.     char *address;
  222.  
  223.     printf("[ Trying SPX ... ]\n");
  224.     strcpy(targ_printable, "SERVICE:rcmd@");
  225.     strcat(targ_printable, RemoteHostName);
  226.  
  227.     input_name_buffer.length = strlen(targ_printable);
  228.     input_name_buffer.value = targ_printable;
  229.  
  230.     if (!UserNameRequested) {
  231.         return(0);
  232.     }
  233.  
  234.     major_status = gss_import_name(&status,
  235.                        &input_name_buffer,
  236.                        GSS_C_NULL_OID,
  237.                        &desired_targname);
  238.  
  239.  
  240.     major_status = gss_display_name(&status,
  241.                     desired_targname,
  242.                     &output_name_buffer,
  243.                     &output_name_type);
  244.  
  245.     printf("target is '%s'\n", output_name_buffer.value); fflush(stdout);
  246.  
  247.     major_status = gss_release_buffer(&status, &output_name_buffer);
  248.  
  249.     input_chan_bindings = (gss_channel_bindings)
  250.       malloc(sizeof(gss_channel_bindings_desc));
  251.  
  252.     input_chan_bindings->initiator_addrtype = GSS_C_AF_INET;
  253.     input_chan_bindings->initiator_address.length = 4;
  254.     address = (char *) malloc(4);
  255.     input_chan_bindings->initiator_address.value = (char *) address;
  256.     address[0] = ((from_addr & 0xff000000) >> 24);
  257.     address[1] = ((from_addr & 0xff0000) >> 16);
  258.     address[2] = ((from_addr & 0xff00) >> 8);
  259.     address[3] = (from_addr & 0xff);
  260.     input_chan_bindings->acceptor_addrtype = GSS_C_AF_INET;
  261.     input_chan_bindings->acceptor_address.length = 4;
  262.     address = (char *) malloc(4);
  263.     input_chan_bindings->acceptor_address.value = (char *) address;
  264.     address[0] = ((to_addr & 0xff000000) >> 24);
  265.     address[1] = ((to_addr & 0xff0000) >> 16);
  266.     address[2] = ((to_addr & 0xff00) >> 8);
  267.     address[3] = (to_addr & 0xff);
  268.     input_chan_bindings->application_data.length = 0;
  269.  
  270.         req_flags = 0;
  271.         if (deleg_flag)  req_flags = req_flags | 1;
  272.         if (mutual_flag) req_flags = req_flags | 2;
  273.         if (replay_flag) req_flags = req_flags | 4;
  274.         if (seq_flag)    req_flags = req_flags | 8;
  275.  
  276.         major_status = gss_init_sec_context(&status,         /* minor status */
  277.                     GSS_C_NO_CREDENTIAL, /* cred handle */
  278.                                         &actual_ctxhandle,   /* ctx handle */
  279.                                         desired_targname,    /* target name */
  280.                                         GSS_C_NULL_OID,      /* mech type */
  281.                                         req_flags,           /* req flags */
  282.                                         0,                   /* time req */
  283.                                         input_chan_bindings, /* chan binding */
  284.                                         GSS_C_NO_BUFFER,     /* input token */
  285.                                         &actual_mech_type,   /* actual mech */
  286.                                         &output_token,       /* output token */
  287.                                         &ret_flags,          /* ret flags */
  288.                                         &lifetime_rec);      /* time rec */
  289.  
  290.     if ((major_status != GSS_S_COMPLETE) &&
  291.         (major_status != GSS_S_CONTINUE_NEEDED)) {
  292.           gss_display_status(&new_status,
  293.                              status,
  294.                              GSS_C_MECH_CODE,
  295.                              GSS_C_NULL_OID,
  296.                              &msg_ctx,
  297.                              &status_string);
  298.           printf("%s\n", status_string.value);
  299.       return(0);
  300.     }
  301.  
  302.     if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
  303.         return(0);
  304.     }
  305.  
  306.     if (!Data(ap, SPX_AUTH, (void *)output_token.value, output_token.length)) {
  307.         return(0);
  308.     }
  309.  
  310.     return(1);
  311. }
  312.  
  313.     void
  314. spx_is(ap, data, cnt)
  315.     Authenticator *ap;
  316.     unsigned char *data;
  317.     int cnt;
  318. {
  319.     Session_Key skey;
  320.     Block datablock;
  321.     int r;
  322.  
  323.     if (cnt-- < 1)
  324.         return;
  325.     switch (*data++) {
  326.     case SPX_AUTH:
  327.             input_token.length = cnt;
  328.         input_token.value = (char *) data;
  329.  
  330.         gethostname(lhostname, sizeof(lhostname));
  331.  
  332.         strcpy(targ_printable, "SERVICE:rcmd@");
  333.         strcat(targ_printable, lhostname);
  334.  
  335.         input_name_buffer.length = strlen(targ_printable);
  336.         input_name_buffer.value = targ_printable;
  337.  
  338.         major_status = gss_import_name(&status,
  339.                                        &input_name_buffer,
  340.                                        GSS_C_NULL_OID,
  341.                                        &desired_targname);
  342.  
  343.         major_status = gss_acquire_cred(&status,
  344.                                         desired_targname,
  345.                                         0,
  346.                                         GSS_C_NULL_OID_SET,
  347.                                         GSS_C_ACCEPT,
  348.                                         &gss_cred_handle,
  349.                                         &actual_mechs,
  350.                                         &lifetime_rec);
  351.  
  352.         major_status = gss_release_name(&status, desired_targname);
  353.  
  354.         input_chan_bindings = (gss_channel_bindings)
  355.           malloc(sizeof(gss_channel_bindings_desc));
  356.  
  357.         input_chan_bindings->initiator_addrtype = GSS_C_AF_INET;
  358.         input_chan_bindings->initiator_address.length = 4;
  359.         address = (char *) malloc(4);
  360.         input_chan_bindings->initiator_address.value = (char *) address;
  361.         address[0] = ((from_addr & 0xff000000) >> 24);
  362.         address[1] = ((from_addr & 0xff0000) >> 16);
  363.         address[2] = ((from_addr & 0xff00) >> 8);
  364.         address[3] = (from_addr & 0xff);
  365.         input_chan_bindings->acceptor_addrtype = GSS_C_AF_INET;
  366.         input_chan_bindings->acceptor_address.length = 4;
  367.         address = (char *) malloc(4);
  368.         input_chan_bindings->acceptor_address.value = (char *) address;
  369.         address[0] = ((to_addr & 0xff000000) >> 24);
  370.         address[1] = ((to_addr & 0xff0000) >> 16);
  371.         address[2] = ((to_addr & 0xff00) >> 8);
  372.         address[3] = (to_addr & 0xff);
  373.         input_chan_bindings->application_data.length = 0;
  374.  
  375.         major_status = gss_accept_sec_context(&status,
  376.                           &context_handle,
  377.                                               gss_cred_handle,
  378.                                               &input_token,
  379.                                               input_chan_bindings,
  380.                                               &src_name,
  381.                                               &actual_mech_type,
  382.                                               &output_token,
  383.                                               &ret_flags,
  384.                                               &lifetime_rec,
  385.                                               &gss_delegated_cred_handle);
  386.  
  387.  
  388.         if (major_status != GSS_S_COMPLETE) {
  389.  
  390.           major_status = gss_display_name(&status,
  391.                       src_name,
  392.                                           &fullname_buffer,
  393.                                           &fullname_type);
  394.             Data(ap, SPX_REJECT, (void *)"auth failed", -1);
  395.             auth_finished(ap, AUTH_REJECT);
  396.             return;
  397.         }
  398.  
  399.         major_status = gss_display_name(&status,
  400.                                           src_name,
  401.                                           &fullname_buffer,
  402.                                           &fullname_type);
  403.  
  404.  
  405.         Data(ap, SPX_ACCEPT, (void *)output_token.value, output_token.length);
  406.         auth_finished(ap, AUTH_USER);
  407.         break;
  408.  
  409.     default:
  410.         Data(ap, SPX_REJECT, 0, 0);
  411.         break;
  412.     }
  413. }
  414.  
  415.  
  416.     void
  417. spx_reply(ap, data, cnt)
  418.     Authenticator *ap;
  419.     unsigned char *data;
  420.     int cnt;
  421. {
  422.     Session_Key skey;
  423.  
  424.     if (cnt-- < 1)
  425.         return;
  426.     switch (*data++) {
  427.     case SPX_REJECT:
  428.         if (cnt > 0) {
  429.             printf("[ SPX refuses authentication because %.*s ]\r\n",
  430.                 cnt, data);
  431.         } else
  432.             printf("[ SPX refuses authentication ]\r\n");
  433.         auth_send_retry();
  434.         return;
  435.     case SPX_ACCEPT:
  436.         printf("[ SPX accepts you ]\n");
  437.         if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
  438.             /*
  439.              * Send over the encrypted challenge.
  440.               */
  441.           input_token.value = (char *) data;
  442.           input_token.length = cnt;
  443.  
  444.           major_status = gss_init_sec_context(&status, /* minor stat */
  445.                                         GSS_C_NO_CREDENTIAL, /* cred handle */
  446.                                         &actual_ctxhandle,   /* ctx handle */
  447.                                         desired_targname,    /* target name */
  448.                                         GSS_C_NULL_OID,      /* mech type */
  449.                                         req_flags,           /* req flags */
  450.                                         0,                   /* time req */
  451.                                         input_chan_bindings, /* chan binding */
  452.                                         &input_token,        /* input token */
  453.                                         &actual_mech_type,   /* actual mech */
  454.                                         &output_token,       /* output token */
  455.                                         &ret_flags,          /* ret flags */
  456.                                         &lifetime_rec);      /* time rec */
  457.  
  458.           if (major_status != GSS_S_COMPLETE) {
  459.             gss_display_status(&new_status,
  460.                        status,
  461.                        GSS_C_MECH_CODE,
  462.                        GSS_C_NULL_OID,
  463.                        &msg_ctx,
  464.                        &status_string);
  465.             printf("[ SPX mutual response fails ... '%s' ]\r\n",
  466.              status_string.value);
  467.             auth_send_retry();
  468.             return;
  469.           }
  470.         }
  471.         auth_finished(ap, AUTH_USER);
  472.         return;
  473.  
  474.     default:
  475.         return;
  476.     }
  477. }
  478.  
  479.     int
  480. spx_status(ap, name, level)
  481.     Authenticator *ap;
  482.     char *name;
  483.     int level;
  484. {
  485.  
  486.     gss_buffer_desc  fullname_buffer, acl_file_buffer;
  487.     gss_OID          fullname_type;
  488.         char acl_file[160], fullname[160];
  489.         int major_status, status = 0;
  490.     struct passwd  *pwd;
  491.  
  492.         /*
  493.          * hard code fullname to
  494.          *   "SPX:/C=US/O=Digital/OU=LKG/OU=Sphinx/OU=Users/CN=Kannan Alagappan"
  495.          * and acl_file to "~kannan/.sphinx"
  496.          */
  497.  
  498.     pwd = getpwnam(UserNameRequested);
  499.     if (pwd == NULL) {
  500.           return(AUTH_USER);   /*  not authenticated  */
  501.         }
  502.  
  503.     strcpy(acl_file, pwd->pw_dir);
  504.     strcat(acl_file, "/.sphinx");
  505.         acl_file_buffer.value = acl_file;
  506.         acl_file_buffer.length = strlen(acl_file);
  507.  
  508.     major_status = gss_display_name(&status,
  509.                     src_name,
  510.                     &fullname_buffer,
  511.                     &fullname_type);
  512.  
  513.     if (level < AUTH_USER)
  514.         return(level);
  515.  
  516.         major_status = gss__check_acl(&status, &fullname_buffer,
  517.                                       &acl_file_buffer);
  518.  
  519.         if (major_status == GSS_S_COMPLETE) {
  520.       strcpy(name, UserNameRequested);
  521.       return(AUTH_VALID);
  522.         } else {
  523.            return(AUTH_USER);
  524.         }
  525.  
  526. }
  527.  
  528. #define    BUMP(buf, len)        while (*(buf)) {++(buf), --(len);}
  529. #define    ADDC(buf, len, c)    if ((len) > 0) {*(buf)++ = (c); --(len);}
  530.  
  531.     void
  532. spx_printsub(data, cnt, buf, buflen)
  533.     unsigned char *data, *buf;
  534.     int cnt, buflen;
  535. {
  536.     char lbuf[32];
  537.     register int i;
  538.  
  539.     buf[buflen-1] = '\0';        /* make sure its NULL terminated */
  540.     buflen -= 1;
  541.  
  542.     switch(data[3]) {
  543.     case SPX_REJECT:        /* Rejected (reason might follow) */
  544.         strncpy((char *)buf, " REJECT ", buflen);
  545.         goto common;
  546.  
  547.     case SPX_ACCEPT:        /* Accepted (name might follow) */
  548.         strncpy((char *)buf, " ACCEPT ", buflen);
  549.     common:
  550.         BUMP(buf, buflen);
  551.         if (cnt <= 4)
  552.             break;
  553.         ADDC(buf, buflen, '"');
  554.         for (i = 4; i < cnt; i++)
  555.             ADDC(buf, buflen, data[i]);
  556.         ADDC(buf, buflen, '"');
  557.         ADDC(buf, buflen, '\0');
  558.         break;
  559.  
  560.     case SPX_AUTH:            /* Authentication data follows */
  561.         strncpy((char *)buf, " AUTH", buflen);
  562.         goto common2;
  563.  
  564.     default:
  565.         sprintf(lbuf, " %d (unknown)", data[3]);
  566.         strncpy((char *)buf, lbuf, buflen);
  567.     common2:
  568.         BUMP(buf, buflen);
  569.         for (i = 4; i < cnt; i++) {
  570.             sprintf(lbuf, " %d", data[i]);
  571.             strncpy((char *)buf, lbuf, buflen);
  572.             BUMP(buf, buflen);
  573.         }
  574.         break;
  575.     }
  576. }
  577.  
  578. #endif
  579.  
  580. #ifdef notdef
  581.  
  582. prkey(msg, key)
  583.     char *msg;
  584.     unsigned char *key;
  585. {
  586.     register int i;
  587.     printf("%s:", msg);
  588.     for (i = 0; i < 8; i++)
  589.         printf(" %3d", key[i]);
  590.     printf("\r\n");
  591. }
  592. #endif
  593.